#!/usr/bin/python
"""
 * test_lib.py - basic python interface to liblwbt.so for testing purposes
 * (C) 2008 by Michael Kramer <kramtek@gmail.com>
 *
"""

import sys
import time

from ctypes import *

# Load lwbt library
liblwbt = CDLL("./lib/liblwbt.so", RTLD_GLOBAL);

#
# Create python wrappers around library functions 
#

# Get the library ready before it can be used 
def setup_library() :
    liblwbt.lib_init()
    liblwbt.lib_setup()

def shutdown_library() :
    liblwbt.lib_shutdown()

# Get the local mac addr and device name
def get_local_mac_addr() :
    addr = c_char_p("none yet")
    liblwbt.get_local_mac_addr(byref(addr))
    return addr.value

def get_local_name() :
    name = c_char_p("none yet")
    liblwbt.get_local_name(byref(name))
    return name.value

def set_local_name(name="temporary") :
    charname = c_char_p(name)
    liblwbt.set_local_name(byref(charname), len(name))

# Scan for discoverable devices 
def scan(scan_time=10, get_names=0) :
    scan_results = c_char_p("none yet")
    numDevices = liblwbt.hci_scan(byref(scan_results), scan_time, 0)
    scan_results = scan_results.value
    print "  Found %d devices" % numDevices
    availDevices = []
    deviceCODs = []
    bdaddr = (c_byte * 6)()
    name = c_char_p("none yet")
    if (numDevices > 0) :
        for index in range(numDevices) :
            availDevices.append(scan_results[(1+index*25):((index+1)*25-7)])
            deviceCODs.append(scan_results[(1+index*25+18):((index+1)*25)])
            if (get_names==0) :
                print "     #%d: %s      COD: %s" % ((index+1), availDevices[index], deviceCODs[index])
            else :
                bt_addr = availDevices[index]
                for index2 in range(6) :
                    bdaddr[index2] = int(bt_addr[0:2], 16)
                    bt_addr = bt_addr[3:len(bt_addr)]

                liblwbt.get_device_name(bdaddr, byref(name))
                print "     #%d: %s\n         %s      COD: %s" % ((index+1), name.value, availDevices[index], deviceCODs[index])
                
    return availDevices

# Initiate an rfcomm connection
def rfcomm_connect(bt_addr=None) :
    bdaddr = (c_byte * 6)()

    if (bt_addr == None) :
        return 0
        
    for index in range(6) :
        bdaddr[index] = int(bt_addr[0:2], 16)
        bt_addr = bt_addr[3:len(bt_addr)]

    response = liblwbt.connect_rfcomm(bdaddr, 1)

    if (response == 10) :
        # Need to request pin code from user  
        raw_pin= raw_input("\n Enter pin-code: ")
        pin = c_char_p(raw_pin)
        response = liblwbt.connect_pin_req(pin, len(raw_pin))
    
    if (response == 6) :
        print "   connection successful!" 
    if (response == 5) :
        print "   connection error: device refused connection"
    if (response == 4) :
        print "   connection error: cannot find SP support on selected device"
    if (response == 3) :
        print "   connection error: no viable sdp record returned"
    if (response == 2) :
        print "   connection error: could not connect to device"

    return response

# Hold in wait loop to demo serving sdp records
def sdp_serv() :
    liblwbt.hci_monitor(0)
    print "going into waiting loop to serve sdp records... (ctrl+c to quit)"
    for index in range(100) :
        time.sleep(0.1)
        #time.sleep(1.4)
        liblwbt.check_input(9) 



#
# Make sure library is initialized and setup before using it
#
setup_library()


#
# Test the library out with some basic calls 
#
print "Local mac address: %s " % get_local_mac_addr()

new_name = "Homer"
print "Setting local name to %s ... " % new_name
set_local_name(new_name)
print "Confirming local name: %s \n" % get_local_name()

print "Setting to discoverable... \n"
liblwbt.set_scan_enable(3)

print "Scanning for other devices..."
availDevices = scan(3,1)

if (len(availDevices) > 0) :
    #raw_value = raw_input("\n  Enter device # to connect to (1-%d) or s to serve sdp records: " % len(availDevices))
    raw_value = raw_input("\n Device # to connect to (1-%d): " % len(availDevices))
    try : 
        value = int(raw_value)
    except : 
        value = 0
    if (value >= 1) & (value <= len(availDevices)) :
        selectedDeviceAddr = availDevices[value-1]
        print "\nAttempting to make rfcomm\n connection to %s..." % selectedDeviceAddr 
        connectResult = rfcomm_connect(selectedDeviceAddr)
        if (connectResult == 6) :
            print "\nPausing before closing connection...\n"
            #time.sleep(10)
            #print "\nStarting rfcomm device i/o ..."
            liblwbt.connect_dev_io()

            #time.sleep(3)
            #data = (c_byte * 7)()
            #data[0] = 1; data[1] = 2; data[2] = 3; data[3] = 4; data[4] = 5; data[5] = 6; data[6] = 7;
            #liblwbt.rfcomm_output( byref(data), 7 )
            #print "  waiting (go check for input...)"
            #time.sleep(15)

            print "   shutting down the connection.\n\n" 

    else :    
        if (raw_value == "s") : 
            print "\nNow serving sdp records ...\n (try to browse from a pc...)"
            sdp_serv()
        else :
            print "\nNot a valid selection.\n"

print "Shutting down the library..."
shutdown_library()
print "End of demonstration."


